package util;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.hadoop.io.WritableComparable;

public class CharacterSet implements WritableComparable<CharacterSet> {

	private Map<Character, Integer> data;
	
	public CharacterSet() {
		data = new HashMap<Character, Integer>();
	}
	
	public CharacterSet(String source) {
		data = new HashMap<Character, Integer>();
		
		for (int i = 0; i < source.length(); i++) {
			add(source.charAt(i));
		}
	}
	
	@Override
	public void write(DataOutput out) throws IOException {
		out.writeInt(size());
		for (Character c : data.keySet()) {
			for (int i = 0; i < data.get(c); i++) {
				out.writeChar(c);
			}
		}
	}

	@Override
	public void readFields(DataInput in) throws IOException {
		int size = in.readInt();
		for (int i = 0; i < size; i++) {
			add(in.readChar());
		}
	}

	public boolean contains(Character character) {
		return data.containsKey(character);
	}
	
	public int size() {
		int size = 0;
		
		for (Character c : data.keySet()) {
			size += data.get(c);
		}
		
		return size;
	}
	
	public void add(Character character) {
		int value = data.get(character) == null ? 0 : data.get(character);
		value++;
		data.put(character, value);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((data == null) ? 0 : data.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		CharacterSet other = (CharacterSet) obj;
		if (data == null) {
			if (other.data != null)
				return false;
		} else if (!data.equals(other.data))
			return false;
		return true;
	}

	@Override
	public int compareTo(CharacterSet o) {
		if (hashCode() - o.hashCode() > 0) {
			return 1;
		} else if (hashCode() - o.hashCode() == 0) {
			return 0;
		}
		return -1;
	}
	
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		for (Character c : data.keySet()) {
			for (int i = 0; i < data.get(c); i++) {
				builder.append(c);
			}
		}
		return builder.toString();
	}
}
